package com.suray.wcs.service.test.action.checkmap.rgv;

import com.github.pagehelper.util.StringUtil;
import com.suray.basic.wcs.path.core.Node;
import com.suray.basic.wcs.utils.LoggerUtil;
import com.suray.commin.core.utils.SpringContextHolder;
import com.suray.wcs.service.pojo.Rgv;
import com.suray.wcs.service.system.service.impl.NodeDBServiceImpl;
import com.suray.wcs.service.util.WcsUtil;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class RgvScanGroundContainer {

    private static NodeDBServiceImpl nodeDBService = SpringContextHolder.getBean(NodeDBServiceImpl.class);

    /**
     * 上次扫到的码的节点
     */
    private Node lastNode;

    /**
     * 上次扫到码时的小车方向
     */
    private Integer lastDirection;

    /**
     * 扫到的地码
     * 同一个节点
     */
    private List<String> groundCodes;

    /**
     * 故障时的地码
     * 放置小车停在异常码处反复报错
     */
    private String errorCode;

    /**
     * 小车
     */
    private Rgv rgv;

    public RgvScanGroundContainer(Rgv rgv) {
        this.rgv = rgv;

        groundCodes = new ArrayList<>();

        lastNode = null;
        lastDirection = null;
        errorCode = "";
    }

    /**
     * 添加地码
     * 如果地码与之前的地码不是同一个坐标，清空之前的地码
     * @param groundCode
     */
    private void inputGroundCode(String groundCode) {
        if (groundCode == null) {
            return;
        } else if (groundCode.length() <= 3) {
            LoggerUtil.warn("RgvScanGroundCode-->>" + rgv.getRgvName() + "地码错误：" + groundCode, this.getClass());
            return;
        }

        if (lastDirection != null && !lastDirection.equals(rgv.getDirection())) {
            //小车换向，清空缓存，从新纪录
            LoggerUtil.info("RgvScanGroundCode-->>" + rgv.getRgvName() + "换向，清除缓存:" + rgv.getDirection(), this.getClass());
            groundCodes.clear();
        }

        if (groundCodes.size() > 0 && groundCodes.get(groundCodes.size() - 1).equals(groundCode)) {
            //同一个码，过滤掉
            return;
        }

        //数据库里面的地码值
        String headCode = groundCode.substring(0, groundCode.length() - 3);

        Node node = null;
        try {
            node = nodeDBService.getNodeByGroundCode(headCode);
        } catch (RuntimeException e) {
            WcsUtil.exceptionLog(e, this.getClass());
            notification(e.getMessage(), groundCode);
            return;
        }

        if (node == null) {
            //如果无法根据地码找到对应的坐标
            notification(lastNode + "节点，小车" + rgv.getDirection() + "方向, 有错误的地码:" + groundCode
                    , groundCode);
            LoggerUtil.info("RgvScanGroundCode-->>" + lastNode + "节点，小车" + rgv.getDirection() + "方向, 有错误的地码:" + groundCode
                    , this.getClass());
            return;
        }

        Iterator<String> codeIt = groundCodes.iterator();

        if (codeIt.hasNext()) {
            String code = codeIt.next();

            if (!code.contains(headCode)) {
                //码改变，清空缓存，重新记录
                if (lastNode.getX() != node.getX() && lastNode.getY() != node.getY()) {
                    //如果检测到地码的坐标与上一个地码的坐标不在一条直线上
                    notification(lastNode + "节点，小车" + rgv.getDirection() + "方向, 有错误的地码:" + groundCode
                            , groundCode);
                    return;
                }

                LoggerUtil.info("RgvScanGroundCode-->>" + rgv.getRgvName() + "扫到的地码不在同一个节点，清除缓存", this.getClass());
                groundCodes.clear();
            }
        }

        groundCodes.add(groundCode);
        lastNode = node;
    }

    /**
     * 分析地码
     */
    protected void analyzeGroundCodes(String groundCode) {
        Integer direction = rgv.getDirection();

        if (direction == null) {
            return;
        } else if (direction < 1 && direction > 4) {
            LoggerUtil.warn("RgvScanGroundCode-->>" + rgv.getRgvName() + "当前方向错误:" + rgv.getDirection(), this.getClass());
            return;
        }

        inputGroundCode(groundCode);

        if (groundCodes.size() >= 2) {
            int[] endCodes = new int[groundCodes.size()];
            int index = 0;
            for (String s : groundCodes) {
                endCodes[index++] = Integer.valueOf(s.substring(s.length() - 3));
            }

            switch (direction) {
                case 1:
                case 2:
                    for (int i = 1; i < endCodes.length; i++) {
                        if (endCodes[i] <= endCodes[i - 1]) {
                            String code = groundCodes.get(0).substring(0, groundCode.length() - 3);
                            Node node = nodeDBService.getNodeByGroundCode(code);
                            notification(node + "节点处码贴反了" + groundCodes.get(i) + "与" + groundCodes.get(i - 1), groundCode);
                            break;
                        }
                    }
                    break;
                case 3:
                case 4:
                    for (int i = 1; i < endCodes.length; i++) {
                        if (endCodes[i] >= endCodes[i - 1]) {
                            String code = groundCodes.get(0).substring(0, groundCode.length() - 3);
                            Node node = nodeDBService.getNodeByGroundCode(code);
                            notification(node + "节点处码贴反了:" + groundCodes.get(i) + "与" + groundCodes.get(i - 1), groundCode);
                            break;
                        }
                    }
                    break;
                default:
                    break;
            }
        }

        if (!StringUtil.isEmpty(errorCode) && !errorCode.equals(groundCode)) {
            errorCode = "";
        }

        lastDirection = direction;
    }

    /**
     * 小铃铛信息
     * @param message
     * @param groundCode
     */
    private void notification(String message, String groundCode) {
        if (errorCode.equals(groundCode)) {
            return;
        }

        errorCode = groundCode;

        WcsUtil.notification(message);
    }
}
